﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Net.Sockets;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using TcpClientService.Helper;

namespace TcpClientService
{
    public partial class Service1 : ServiceBase
    {
        LogHelper logHelper = new LogHelper();
        private TcpClient client; // TcpClient实例
        private NetworkStream stream; // 网络流，用于与服务器通信
        string tcpServer = "127.0.0.1";
        string port = "30001";
        public Service1()
        {
            InitializeComponent();
            tcpServer = ConfigurationManager.AppSettings.Get("TcpServer");
            port = ConfigurationManager.AppSettings.Get("TcpServerPort");
        }

        protected async override void OnStart(string[] args)
        {
            while (true)
            {
                try
                {
                    if (client == null || !client.Connected)
                    {
                        await ConnectToServer(tcpServer, int.Parse(port));
                    }
                    bool result = await Send("1");
                    if (!result)
                    {
                        client.Close();
                    }
                }catch(Exception ex)
                {
                    logHelper.Error($"【服务器状态】- 错误{ex.Message} \r\n {ex.StackTrace}");
                }
                Thread.Sleep(1000);
            }
        }

        protected override void OnStop()
        {
            if (client != null)
            {
                client.Close();
            }
        }

        /// <summary>
        /// 连接到服务器
        /// </summary>
        /// <param name="server">服务器IP地址或主机名</param>
        /// <param name="port">端口号</param>
        private async Task<bool> ConnectToServer(string server, int port)
        {
            try
            {
                // 创建一个TcpClient实例
                client = new TcpClient();

                // 异步连接到指定的服务器IP和端口
                await client.ConnectAsync(server, port);

                // 获取与服务器通信的网络流
                stream = client.GetStream();

                // 启动一个异步任务接收来自服务器的消息
                bool result = await ReceiveMessages();
                return result;
            }
            catch (Exception ex)
            {
                // 如果在尝试连接过程中发生异常，显示错误消息
                logHelper.Error($"【连接服务】- 错误{ex.Message} \r\n {ex.StackTrace}");
                if (client != null)
                {
                    client.Close();
                }
                return false;
            }
        }

        /// <summary>
        /// 发送消息到服务器
        /// </summary>
        /// <param name="message">要发送的消息</param>
        private async Task<bool> Send(string message)
        {
            try
            {
                // 检查网络流是否已经初始化，确保我们可以发送数据
                if (stream != null)
                {
                    // 将字符串消息转换为UTF-8编码的字节数组
                    byte[] data = Encoding.UTF8.GetBytes(message);

                    // 异步地将数据写入网络流
                    // 这是发送数据到服务器的实际操作
                    await stream.WriteAsync(data, 0, data.Length);
                    return true;
                }
                else
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                // 如果在发送数据过程中发生异常（如连接断开），显示错误消息
                logHelper.Error($"【向Server发送数据】- 错误 {ex.Message} \r\n {ex.StackTrace}");
                return false;
            }
        }

        /// <summary>
        /// 异步接收来自服务器的消息
        /// </summary>
        private async Task<bool> ReceiveMessages()
        {
            try
            {
                // 创建一个缓冲区用于接收数据
                byte[] buffer = new byte[1024];
                int numberOfBytesRead;

                // 循环读取网络流中的数据，直到没有更多数据
                while ((numberOfBytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0)
                {
                    // 将接收到的字节数据转换为字符串
                    string receivedMessage = Encoding.UTF8.GetString(buffer, 0, numberOfBytesRead);

                    // 在UI线程上安全地更新文本框以显示接收到的消息
                    // 这是必要的，因为ReceiveMessages不在UI线程上运行
                    logHelper.Debug($"【数据接收】- {receivedMessage} \r\n");
                }
                return true;
            }
            catch (Exception ex)
            {
                // 如果在接收数据过程中发生异常（如连接断开），显示错误消息
                logHelper.Error($"【数据接收】- 错误 {ex.Message} \r\n {ex.StackTrace}");
                return false;
            }
        }

        private void ClosePc(string command)
        {
            if (command.ToLower().Contains("shutdown"))
            {
                // 创建一个新的ProcessStartInfo对象
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.FileName = "shutdown.exe"; // 指定命令
                startInfo.Arguments = "/s /f /t 0"; // /s 关闭，/t 延迟时间
                startInfo.UseShellExecute = true; // 允许使用Shell执行
                startInfo.Verb = "runas"; // 提升为管理员权限

                try
                {
                    // 启动进程
                    Process.Start(startInfo); 
                    logHelper.Debug($"【关机】- 成功");
                }
                catch (Exception ex)
                {
                    logHelper.Error($"【关机】- 失败 {ex.Message } \r\n {ex.StackTrace}");
                }
            }
        }
    }
}
